package br.com.klis.batendoumabola.server;

import java.util.ArrayList;

import br.com.klis.batendoumabola.client.exception.DaoException;
import br.com.klis.batendoumabola.client.exception.NotLoggedInException;
import br.com.klis.batendoumabola.client.exception.UsuarioInconsistenteException;
import br.com.klis.batendoumabola.client.service.PeladaService;
import br.com.klis.batendoumabola.server.util.DateUtil;
import br.com.klis.batendoumabola.shared.BateBolaVerifier;
import br.com.klis.batendoumabola.shared.Pelada;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

@SuppressWarnings("serial")
public class PeladaServiceImpl extends RemoteServiceServlet implements PeladaService {

	// private static final Logger LOG =
	// Logger.getLogger(PeladaServiceImpl.class.getName());
	static {
		ObjectifyService.register(Pelada.class);
	}

	@Override
	public Boolean existeBateBolaDoUsuario(Pelada pelada) throws NotLoggedInException, DaoException{
		checkLoggedIn();
		boolean retorno;
		Objectify ofy = ObjectifyService.begin();
		Query<Pelada> q = ofy.query(Pelada.class).filter("user",
				getUser().getEmail()).filter("nomeUC", pelada.getNome().toUpperCase());
		if (q != null && q.countAll() > 0){
			retorno = true;
			for(Pelada p:q){
				if (pelada.getId() != null && pelada.getId().equals(p.getId()) && p.getNome().equals(pelada.getNome())){
					try {
						checkLoggedIn(p.getUser());
					} catch (UsuarioInconsistenteException e) {
						throw new DaoException("O Usuário logado não é o Líder do Bate-Bola.");
					}
					retorno = false;
					break;
				}
			}
		}else{
			retorno = false;
		}
		return retorno;
	}
	
	@Override
	public ArrayList<Pelada> getPeladasByLoggedUser() throws NotLoggedInException {
		checkLoggedIn();
		Objectify ofy = ObjectifyService.begin();
		ArrayList<Pelada> peladas = new ArrayList<Pelada>();
		Query<Pelada> q = ofy.query(Pelada.class).filter("user", getUser().getEmail());
		for (Pelada p : q) {
			peladas.add(p);
		}
		return peladas;
	}

	private void checkLoggedIn() throws NotLoggedInException {
		if (getUser() == null) {
			throw new NotLoggedInException("Not logged in.");
		}
	}
	
	private void checkLoggedIn(String email) throws NotLoggedInException, UsuarioInconsistenteException {
		if (getUser() == null) {
			throw new NotLoggedInException("Not logged in.");
		}
		if (!getUser().getEmail().equals(email)){
			throw new UsuarioInconsistenteException("Usuario inconsistente.");
		}
	}

	private User getUser() {
		UserService userService = UserServiceFactory.getUserService();
		return userService.getCurrentUser();
	}

	public ArrayList<Pelada> getAllPeladas() {
		System.out.println(">>entrou no search peladas...");
		Objectify ofy = ObjectifyService.begin();
		ArrayList<Pelada> peladas = new ArrayList<Pelada>();
		
		Query<Pelada> query = ofy.query(Pelada.class);
		 for (Pelada p : query) {
				peladas.add(p);
			}
		return peladas;
	}
	
	public ArrayList<Pelada> pesquisarPeladas(Pelada pelada) {
		System.out.println(">>entrou no search peladas...");
		if(pelada.getDataTexto() == null){
			//se a pesquisa for originada pelo servico rest, entao ja tera a dataTexto setada
			pelada.setDataTexto(DateUtil.convertDateToString(pelada.getData()));	
		}
		
		Objectify ofy = ObjectifyService.begin();
		ArrayList<Pelada> peladas = new ArrayList<Pelada>();
		
		Query<Pelada> query = ofy.query(Pelada.class);
		 if(pelada.getNome() != null && !pelada.getNome().equals("")){
			 System.out.println("Qual server: "+ pelada.getNome());
			 query.filter("nomeUC", pelada.getNome().toUpperCase());
		 }
		 
		 if(pelada.getDataTexto() != null){
			 System.out.println("Quando server: "+ pelada.getData());
			 query.filter("dataTexto",pelada.getDataTexto());
		 }
		 
		 if(pelada.getCidade() != null && !pelada.getCidade().equals("")){
			 System.out.println("Onde server: "+ pelada.getCidade());
			 query.filter("cidadeUC",pelada.getCidade().toUpperCase());
		 }
		 
		 if(pelada.getLocal() != null && !pelada.getLocal().equals("")){
			 System.out.println("Onde Local server: "+ pelada.getLocal());
			 query.filter("localUC",pelada.getLocal().toUpperCase());
		 }
		 
		 if(pelada.getTemVagas() != null){
			 System.out.println("Detalhe Tem Vagas server: "+ pelada.getTemVagas());
			 query.filter("temVagas",pelada.getTemVagas());
		 }
		 
		 if(pelada.getGratuito() != null){
			 System.out.println("Detalhe Gratuito server: "+ pelada.getGratuito());
			 query.filter("gratuito",pelada.getGratuito());
		 }
		 
		 for (Pelada p : query) {
				System.out.println(">>> PELADA SERVER: " + p.getNome());
				peladas.add(p);
			}		
		return peladas;
	}
	
	@Override
	public Boolean atualizarDadosAdm() throws NotLoggedInException, DaoException{
		checkLoggedIn();
		ArrayList<Pelada> peladas = getAllPeladas();
		Objectify ofy = ObjectifyService.begin();
		
		for (Pelada p : peladas) {
			p.setDataTexto(DateUtil.convertDateToString(p.getData()));
			ofy.put(p);
		}
		return true;
	}

	@Override
	public ArrayList<Pelada> deletePeladas(ArrayList<Pelada> peladas) throws NotLoggedInException {
		checkLoggedIn();
		System.out.println("Excluindo " + peladas.size() + "peladas...");
		Objectify ofy = ObjectifyService.begin();
		ofy.delete(peladas);
		ArrayList<Pelada> peladasRestantes = getPeladasByLoggedUser();
		System.out.println("Peladas no banco " + peladasRestantes.size());
		return peladasRestantes;
	}

	@Override
	public Boolean deletePelada(Pelada pelada) throws NotLoggedInException {
		checkLoggedIn();
		Objectify ofy = ObjectifyService.begin();
		ofy.delete(pelada);
		System.out.println("Pelada " + pelada.getNome() + " deletada por "
				+ getUser());
		return true;
	}

	@Override
	public Pelada getPeladaById(String id) {
		System.out.println(">>entrou no getPeladaById...");
		Objectify ofy = ObjectifyService.begin();
		Pelada pelada = ofy.find(Pelada.class, new Long(id));
		return pelada;
	}

	@Override
	public Pelada savePelada(Pelada pelada) throws NotLoggedInException,DaoException {
		checkLoggedIn();
		if (existeBateBolaDoUsuario(pelada)){
			throw new DaoException("Você Já cadastrou um Bate-Bola com o nome " + pelada.getNome() + ".");
		}
		String retorno = BateBolaVerifier.isValid(pelada);
		if (retorno != "") {
			throw new DaoException(retorno);
		}
		pelada.setDataTexto(DateUtil.convertDateToString(pelada.getData()));
		Objectify ofy = ObjectifyService.begin();
		setUser(pelada);
		ofy.put(pelada);
		System.out.println("Pelada " + pelada.getNome() + " atualizada por " + getUser());
		return pelada;
	}

	public void setUser(Pelada pelada) throws DaoException {
		pelada.setUser(getUser().getEmail());
	}
	
	
	
	

}
